In this step of the tutorial you export the kzb files for both baked themes (defined in the Car variant theme group) and non-baked themes (defined in the Cluster theme theme group), and use the Kanzi Engine API to enable the user to change the non-baked themes in the application.
In this section you first set in the Kanzi Studio project how you want to export the themes in the project, then you export the themes.
This section shows how to export themes you defined in the Cluster theme theme group with themes you defined in the Car variant theme group as theme packs. A Theme resource pack is a kzb file which contains only the resources for a selected Theme. Use this approach when the storage or memory on your target device is limited, but you want to change the application theme at runtime without having to load additional kzb files. For example, with this approach you can create from one Kanzi Studio project applications for two car variants (Gasoline and Hybrid), where each has two themes (Classic and Modern) between which you can switch in the application.
This is just one of the approaches of how you can export themes from your project. To find the approach that is most suitable for your product and target hardware, see Exporting Themes.
To export kzb files:
theming.kzbto
Car variant=Gasoline/theming.kzb
theming.kzbto
Car variant=Hybrid/theming.kzb
In this section you add the application code to start the application with the Classic theme and create a message handler which you add to the Theme selector Button 2D node to switch between the two themes you created in the Cluster theme theme group.
To add code to change the cluster theme:
If you open the tutorial solution in Visual Studio 2017, when asked to retarget the project to the latest Microsoft toolset, click Cancel.
Theming
class create:class Theming : public ExampleApplication { // Structure describing a theme. struct ThemeDescriptor { explicit ThemeDescriptor(const string& name, const string& url): m_name(name), m_url(url) { } // The name of the theme. string m_name; // The kzb file URL of the theme. string m_url; }; // Collection of all theme descriptions. vector<ThemeDescriptor> m_themes; // The index of the currently active theme. int m_activeThemeIndex; // The name of the baked theme to load. static const string m_carVariant; ... }
Theming
class use the m_carVariant
variable you created in the previous step, to set which car variant you want to load at application startup.// Select which baked theme to use. // To start the application for the Hybrid car variant, set to 0. // To start the application for the Gasoline car variant, set to 1. #if 1 const string Theming::m_carVariant = "Gasoline"; #else const string Theming::m_carVariant = "Hybrid"; #endif
onConfigure()
function use the .kzb.cfg file Kanzi Studio creates when exporting kzb file to load the application with the baked theme you can set in the previous step.virtual void onConfigure(ApplicationProperties& configuration) KZ_OVERRIDE { configuration.binaryName = "./Car variant=" + m_carVariant + "/theming.kzb.cfg"; configuration.defaultWindowProperties.width = 1920; configuration.defaultWindowProperties.height = 720; }
onProjectLoaded()
functionvirtual void onProjectLoaded() KZ_OVERRIDE { // Add names and URLs for all themes. m_themes.push_back(ThemeDescriptor("Classic", "kzb://theming/Themes/Cluster theme/Classic")); m_themes.push_back(ThemeDescriptor("Modern", "kzb://theming/Themes/Cluster theme/Modern")); // Load metadata from all kzb files which contain theme resources. ResourceManager* resourceManager = getResourceManager(); resourceManager->addKzbFile("./Car variant=" + m_carVariant + "/Theme_packs/Cluster theme=Classic.kzb"); resourceManager->addKzbFile("./Car variant=" + m_carVariant + "/Theme_packs/Cluster theme=Modern.kzb"); // Activate the first theme at application startup. m_activeThemeIndex = -1; changeToNextTheme(); }
onProjectLoaded()
function create a function you use to activate the next theme in your application.// Activates the next theme. void changeToNextTheme() { // Get the Text Block 2D node in the Theme selector Button 2D node so that you can change the text to show the name of the next theme. Button2DSharedPtr themeSelectorButton = getRoot()->lookupNode<Button2D>("Theme selector"); TextBlock2DSharedPtr selectorThemeTextBlock = themeSelectorButton->lookupNode<TextBlock2D>("#Next theme name"); // Get the descriptors for the next theme and the theme following the next theme. const int nextThemeIndex = (m_activeThemeIndex + 1) % m_themes.size(); const int followingThemeIndex = (m_activeThemeIndex + 2) % m_themes.size(); const ThemeDescriptor& nextTheme = m_themes.at(nextThemeIndex); const ThemeDescriptor& followingTheme = m_themes.at(followingThemeIndex); // Set the name of the following theme. selectorThemeTextBlock->setText(followingTheme.m_name); // Set the application theme to the next theme. getScreen()->activateTheme(nextTheme.m_url); m_activeThemeIndex = nextThemeIndex; }
Theming
class after the onProjectLoaded()
function create the onChangeThemeButtonClicked
event handler where you define how the application reacts when user clicks the Theme selector button in the application. // This message handler defines how the application reacts when the user clicks the Theme selector button in the application.
void onChangeThemeButtonClicked(ButtonConcept::ClickedMessageArguments& /* messageArguments */)
{
changeToNextTheme();
}
onProjectLoaded()
function after loading the metadata from theme kzb files add the message handler you created in the previous step to the Theme selector node.virtual void onProjectLoaded() KZ_OVERRIDE { ... // Register the message handler for the Button: Click message used by the Theme selector node. Button2DSharedPtr themeSelectorButton = getRoot()->lookupNode<Button2D>("Theme selector"); themeSelectorButton->addMessageHandler(ButtonConcept::ClickedMessage, bind(&Theming::onChangeThemeButtonClicked, this, placeholders::_1)); ... }
In the application when you click the Theme selector button, you switch between the Classic and Modern cluster themes which you defined in the Cluster theme theme group.
In this tutorial you learned how to theme a Kanzi application to create different appearance of the same application and how to use a single Kanzi Studio project for more than one variant of your product. To take this tutorial further you can create assets for additional cluster themes and car variants. You can also:
To find out more about how to create themes for your Kanzi applications, see Theming your applications.
To learn more about the different options for exporting themes from your Kanzi Studio project, see Exporting Themes.
To learn how to create and use styles, see Using styles.
To learn more about using state managers in your Kanzi applications, see Tutorial: Use state managers to control your application and Using state managers.
To learn more about Prefab Placeholder and Prefab View nodes, and how to use them, see Using prefabs.